#ifndef __LL_MAKE_DEPENDENCE_HPP__
#define __LL_MAKE_DEPENDENCE_HPP__

#include <list>
#include <string>
using namespace std;

#include <fstream>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>

namespace llmake
{
	class llDependenceNode
	{
	    friend class boost::serialization::access;
		template<class Archive>
		void serialize(Archive & ar, const unsigned int /* file_version */)
		{
			ar  & BOOST_SERIALIZATION_NVP(m_FileName)
				& BOOST_SERIALIZATION_NVP(m_TimeStamp);
		}

	public:
		llDependenceNode(){}
		llDependenceNode(const string & name);
		~llDependenceNode(){}
		void update(void);
		bool operator == (const llDependenceNode &obj)
		{
			return this->m_FileName == obj.m_FileName && this->m_TimeStamp == obj.m_TimeStamp;
		}
// members
	private:
		string m_FileName;
		time_t m_TimeStamp;
	};

	class llDependencePair
	{
	    friend class boost::serialization::access;
		template<class Archive>
		void serialize(Archive & ar, const unsigned int /* file_version */)
		{
			ar  & BOOST_SERIALIZATION_NVP(m_First)
				& BOOST_SERIALIZATION_NVP(m_Remains);
		}
// compare 
		friend bool operator == (llDependencePair &left,llDependencePair &right)
		{
			if( false == ( left.m_First == right.m_First ) )
			{
				return false;
			}
			list<llDependenceNode>::iterator leftIr = left.m_Remains.begin();
			list<llDependenceNode>::iterator rightIr = right.m_Remains.begin();
			for(; left.m_Remains.end() != leftIr && right.m_Remains.end() != rightIr;leftIr++,rightIr++ )
			{
				if( false == (*leftIr == *rightIr ) )
				{
					return false;
				}
			}
			if(left.m_Remains.end() != leftIr || right.m_Remains.end() != rightIr )
			{
				return false;
			}
			return true;
		}
	public:
		llDependencePair(){}
		llDependencePair(const llDependenceNode &first)
			:m_First(first)
		{}
		llDependencePair(const llDependenceNode &first,list<llDependenceNode> &remain)
			:m_First(first)
			,m_Remains(remain)
		{}
		~llDependencePair(){}
		void update(void)
		{
			m_First.update();
			list<llDependenceNode>::iterator it = m_Remains.begin();
			for( ; m_Remains.end() != it ; it++ )
			{
				it->update();
			}
		}
		void append(list<llDependenceNode> &nodes)
		{
			list<llDependenceNode>::iterator nodeIr = nodes.begin();
			for( ; nodes.end() != nodeIr ; nodeIr++ )
			{
				m_Remains.push_back(*nodeIr);
			}
		}
// members
	private:
		llDependenceNode			m_First;
		list<llDependenceNode>		m_Remains;
	};
	typedef map<string,llDependencePair> llDependenceMap;

	class llDependenceEngine
	{
	public:
		llDependenceEngine(const string &dir)
			:m_XmlSerialize(dir +"/LLMake_serialize.xml")
		{}
		~llDependenceEngine(){}
		void load(void);
		void save(void);
		bool parseDependence(list<string> &first,list<string> &remains);
	private:
		llDependenceMap				m_LastDep;
		llDependenceMap				m_CurDep;
		string						m_XmlSerialize;
	};
};
#endif // __LL_MAKE_DEPENDENCE_HPP__
